package com.jokerpan.project.controller;

import com.jokerpan.project.annotation.AccessLimit;
import com.jokerpan.project.annotation.LogAction;
import com.jokerpan.project.commons.ActionResult;
import com.jokerpan.project.commons.ListResult;
import com.jokerpan.project.commons.ResultBuilder;
import com.jokerpan.project.entity.Users;
import com.jokerpan.project.service.UsersService;
import com.jokerpan.project.util.MD5Util;
import com.jokerpan.project.util.UserTool;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author jokerpan
 * @date 2022-3-9
 */
@RestController
@RequestMapping("users")
@RefreshScope   //对Bean进行动态刷新，添加 @RefreshScope 或 @ConfigurationProperties注解。
@Api("用户操作Api")
public class UsersController {
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Resource
    public UsersService usersService;
    @Value("${server.port}")
    public String port;
    @Resource
    public RedisTemplate redisTemplate;
    @Resource
    UserTool userTool;

    /**
     * 查询所有数据
     * @return 对象列表
     */
    @GetMapping("/queryList")
    @AccessLimit(seconds = 6, maxCount = 5)
    @PreAuthorize("hasPermission('','admin:list')")
    @ApiOperation("查询所有用户")
    public ListResult<Object> queryList(Users users) {
        return ResultBuilder.buildListSuccess(this.usersService.queryList(users));
    }

    /**
     * 根据id查询单个对象
     * @param id
     * @return
     */
    @GetMapping("/queryById")
    @AccessLimit(seconds = 6, maxCount = 5)
    @PreAuthorize("hasPermission('','user:list')")
    @ApiOperation("根据id查询单个用户")
    public Users queryById(@RequestParam("id") Integer id){
        return usersService.queryById(id);
    }

    /**
     * 登录 (已作废)
     * @return 是否成功
     */
    //@PostMapping("/login")
    public Map<String, Object> login(Users users) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        boolean flag;
        Map<String, Object> map = new HashMap<>();
        Users user = usersService.checkLoginName(users.getLoginName());
        if (user != null){
            if (MD5Util.validPassword(users.getPassword(), user.getPassword())){
                //验证成功！
                flag =  true;
                ValueOperations<String, Users> operations = redisTemplate.opsForValue();
                String key = "user_" + user.getId();
                boolean hasKey = redisTemplate.hasKey(key);
                if (hasKey){
                    redisTemplate.delete(key);
                }
                operations.set(key, user, 5, TimeUnit.HOURS);
            }else {
                flag =  false;
            }
        }else {
            flag = false;
        }
        map.put("status",flag);
        map.put("message", flag ? "登录成功!" : "登录失败!!!");
        log.info(flag ? "登录成功!" : "登录失败!!!");
        map.put("data", user);
        return map;
    }

    /**
     * 用户注册
     * @param users
     * @return 是否成功
     */
    @PostMapping("/register")
    @AccessLimit(seconds = 6, maxCount = 5)
    @ApiOperation("用户注册")
    public Map<String, Object> register(Users users){
        Map<String, Object> map = new HashMap<>();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Integer status = 0;
        users.setPassword(new BCryptPasswordEncoder().encode(users.getPassword()));
        users.setAddress("");
        users.setAge(null);
        users.setAvatar("http://www.jokerpan.xyz:8080/images/noavatar.svg");
        users.setName(users.getLoginName());
        users.setSex("");
        users.setSignature("");
        users.setTags("");
        users.setBackupEmail("");
        users.setBackupQuestion("");
        users.setBackupPhone("");
        users.setLastLoginTime(null);
        users.setCreateTime(format.format(new Date()));
        Users user = usersService.checkLoginName(users.getLoginName());
        if (user == null){
            if(users.getLoginName().length() <= 10){
                status = 1;
                usersService.add(users);
            }else {
                status = 4;
            }
        }else if (user != null){
            status = 2;
        }else {
            status = 3;
        }
        map.put("status", status);
        return map;
    }

    /**
     * 修改用户
     * @param users
     * @return 是否成功
     */
    @PostMapping("/update")
    @AccessLimit(seconds = 6, maxCount = 5)
    @PreAuthorize("hasPermission('','user:update')")
    @LogAction("用户管理,用户信息数据修改,用户信息修改,修改")
    @ApiOperation("用户信息修改")
    public ListResult<Object> update(@RequestBody Users users) {
        if (StringUtils.isNotBlank(users.getOldpassword()) && StringUtils.isNotBlank(users.getNewpassword())){
            Users u = userTool.getCurrentUser();
            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            if (bCryptPasswordEncoder.matches(users.getOldpassword(), u.getPassword())){
                users.setPassword(bCryptPasswordEncoder.encode(users.getNewpassword()));
                if (usersService.update(users)){
                    return ResultBuilder.buildListSuccess("修改密码成功！");
                }else {
                    return ResultBuilder.buildListFail("修改密码失败！");
                }
            }else {
                return ResultBuilder.buildListFail("原密码错误！");
            }
        }
        users.setName(users.getLoginName());
        Users user = usersService.checkLoginName(users.getLoginName());
        if (user == null){
            if (usersService.update(users)){
                return ResultBuilder.buildListSuccess("修改用户信息成功！");
            }
        }else if (user != null){
            return ResultBuilder.buildListFail("用户名已存在！");
        }
        return ResultBuilder.buildListFail("修改用户信息失败！");
    }

    @GetMapping("/testNacos")
    @AccessLimit(seconds = 6, maxCount = 5)
    @PreAuthorize("hasAnyRole('ROLE_USER','ROLE_ADMIN')")
    @ApiOperation("测试nacos")
    public String testNacos(){
        return this.port;
    }

    @GetMapping("/testRedis")
    @AccessLimit(seconds = 6, maxCount = 5)
    @PreAuthorize("hasAnyRole('ROLE_USER','ROLE_ADMIN')")
    @ApiOperation("测试redis")
    public Object testRedis(@RequestParam("id") Integer id){
        ValueOperations<String, Users> operations = redisTemplate.opsForValue();
        String key = "user_" + id;
        boolean hasKey = redisTemplate.hasKey(key);
        Object o;
        if (hasKey){
            log.info("从redis中拿到数据");
            o = operations.get("user_" + id);
        }else {
            log.info("从数据库中拿到数据");
            o = usersService.queryById(id);
        }
        return o;
    }

    /**
     * 获取当前登录的用户
     */
    @GetMapping("/getCurrentUser")
    @AccessLimit(seconds = 6, maxCount = 5)
    @ApiOperation("获取当前登录的用户")
    public ListResult<Object> getCurrentUser() {
        Users users = userTool.getCurrentUser();
        if (users != null){
            return ResultBuilder.buildListSuccess(users);
        }else {
            return ResultBuilder.buildListFail("需要登录！");
        }
    }

    @GetMapping("/saveUser")
    @AccessLimit(seconds = 6, maxCount = 5)
    @ApiOperation("保存用户信息至redis")
    public ActionResult saveUserToRedis(){
        if (userTool.putUserToRedis()){
            return ResultBuilder.buildActionSuccess();
        }else {
            return ResultBuilder.buildActionFailed();
        }
    }

    @GetMapping("/clearUser")
    @AccessLimit(seconds = 6, maxCount = 5)
    @ApiOperation("清除当前登录用户信息")
    public ActionResult clearUser(){
        if (userTool.clearCurrentUser()){
            return ResultBuilder.buildActionSuccess();
        }else {
            return ResultBuilder.buildActionFailed();
        }
    }

    @GetMapping("/deleteById")
    @AccessLimit(seconds = 6, maxCount = 5)
    @PreAuthorize("hasPermission('','admin:delete')")
    @LogAction("用户管理,删除用户数据,删除用户,删除")
    @ApiOperation("根据id删除用户")
    public ActionResult deleteUser(@RequestParam("id") Integer id){
        if (usersService.deleteById(id)){
            return ResultBuilder.buildActionSuccess();
        }else {
            return ResultBuilder.buildActionFailed();
        }
    }

    @GetMapping("/testRole")
    @AccessLimit(seconds = 6, maxCount = 5)
    @PreAuthorize("hasPermission('','add')")
    public String testRole(){
        return "success!!!";
    }

}